导航菜单
首页 >  Garbage Collection in Java Managing Memory Automatically  > Java Memory Management 101: Java Garbage Collection

Java Memory Management 101: Java Garbage Collection

Java Memory Management 101: Java Garbage CollectionMurat

Murat

·

Follow

9 min read·Jan 3, 2023

--

If you’re a Java programmer, you may be familiar with the Java Virtual Machine (JVM) and the role it plays in running Java programs. One important aspect of the JVM is the garbage collection mechanism, which is responsible for freeing up memory that is no longer being used by a Java program.

In Java, memory is managed automatically using a combination of heap and stack memory. Heap memory is where objects are stored, while Stack memory is used to store primitive data types and references to objects.

As a Java program runs, it creates and uses objects, which consume heap memory. When an object is no longer being used, it becomes eligible for garbage collection. The garbage collector is responsible for identifying these unused objects and reclaiming the heap memory they occupy.

In this blog we will try to cover Garbage Collection with these sections: Generations with GC, GC Steps, GC Process and Garbage Collectors.

Garbage Collection

Garbage collection is the process of looking at heap memory, identifying which objects are in use and which are not, and deleting the unused objects.

Heap Space Representation with GC

To understand this section, you may need knowledge about heap space. You can read this article to learn about heap memory.

Java Memory Management 101: Heap Memory

The Young Generation is where all newly created objects are allocated and aged (aging is covered in GC process section). When the young generation fills up, Minor Garbage Collection is performed and clear all unreferenced objects in young generation space.

Objects that are still being referenced by active threads and have survived the garbage collection cycle are promoted from the young generation to the old generation. When the old generation fills up, Major Garbage Collection process is performed.

Both Major Garbage Collection and Minor Garbage Collection process “STOPS THE WORLD”.Stops the World?

When the garbage collector runs, it needs to stop all threads in the application so that it can safely determine which objects are no longer being used and can be collected. This pause is known as a “stop-the-world” event.

Minor Garbage collection is work on Young generation and Major Garbage Collection works on across the Heap and stops the world. Often a major collection is much slower because it involves all live objects.

There are a variety of techniques that can be used to reduce the impact of garbage collection on application performance, such as using parallel and concurrent garbage collectors.

GC Steps

Garbage collection then goes through the three phases: mark, sweep, and, if required, compaction.

Marking: The process of garbage collection involves starting at the root node of the object graph (e.g., the main function in a program), and then traversing the object graph to identify objects that are reachable (i.e., still being used by the program) and unreachable (i.e., no longer being used by the program). The GC algorithm will then mark the unreachable objects as eligible for collection.

Marking Memory Illustration

Delete/sweep: After marking process, garbage collectors reclaim the memory occupied by unreachable objects which are marked as unreachable.

Delete/sweep Memory Illustration

After compacting process, Memory Allocator keeps list of references to free space in order to give free spaces when an allocation required.

Compacting: Memory compaction is a process used by some garbage collection (GC) algorithms to defragment the memory heap and improve memory utilization. During compaction, the GC algorithm identifies objects that are no longer in use and reclaims their memory. It then moves the remaining objects closer together, making the allocation of memory more contiguous and reducing the amount of fragmentation. This can help to improve the efficiency of the program, as it may be able to access memory more quickly when it is contiguous, rather than having to search through fragmented blocks of memory.

Compacting Memory Illustration

After compacting process, Memory Allocator keeps the beginning of references to free space in order to allocate memory squentially.

Garbage Collection ProcessThe first step is to allocate any new objects to the eden space. Both survivor spaces start out empty.

2. Minor garbage collection is triggered, when the Eden space fills up.

3. During the garbage collection process, objects that are still being referenced by active threads are moved from the eden space to the first survivor space. Objects that are no longer referenced, or “unreferenced objects,” are deleted when the eden space is cleared. This helps to free up memory that is no longer being used by the program.

4. During the next minor garbage collection cycle, the same process occurs for the eden space. Unreferenced objects are deleted and referenced objects are moved to a survivor space. However, in this case, they are moved to the second survivor space (S1). In addition, objects from the last minor GC on the first survivor space (S0) have their age incremented and get moved to S1.

After the garbage collection process has moved all surviving objects from the eden space to the first survivor space (S1), both the eden space and the first survivor space (S0) are cleared.

5. Additional Minor GC process repeats. However this time the survivor spaces swtich.

Maybe you have a confisuon about Why young generation has two survivor space?

In order to make contiguous (linear) access and avoid another reordering process with two space moving around and make them contiguous and relevant access. It prevents fragmentation.

6. After a minor garbage collection cycle, surviving objects that have reached a certain age threshold are “promoted” from the young generation to the old generation. In this example threshold is “7”.

Garbage Collectors

One common misunderstanding about the Java Virtual Machine (JVM) is the belief that it only has a single garbage collector. In reality, the JVM offers four distinct garbage collectors to choose from, each with its own pros and cons. These garbage collectors include the Serial GC, Parallel GC, Concurrent Mark Sweep (CMS) GC, and Garbage First (G1) GC. Each of these garbage collectors has specific features and characteristics that make them more or less suitable for certain types of applications and environments.

The choice of which Garbage Collector to use isn’t automatic and lies on your shoulders and the differences in throughput and application pauses can be dramatic.

Serial collector is the simplest one, and the one you probably won’t be using. This garbage collector is suitable for small and simple applications that have a single processor. It uses a single thread to perform garbage collection, which makes it relatively simple to implement.

You can use it by turning on this JVM argument:

java -XX:+UseSerialGC -jar myapp.jar

Parallel Collector / Throughput Collector is the JVM’s default collector. This garbage collector is designed for multi-processor systems and uses multiple threads to perform garbage collection in parallel.

The downside to the parallel collector is that it will “Stops the World” when performing either a Minor or Major GC collection.

The parallel collector is best suited for apps that can tolerate application pauses and are trying to optimize for lower CPU overhead caused by the collector.

Concurrent Collector is designed to perform garbage collection concurrently with the application. It uses multiple threads to mark and sweep objects that are no longer in use, which can reduce the overall pause time of the garbage collection process. CC only stops the world only during mark/re-mark steps.

One concern when using a garbage collector that utilizes a mark-sweep-compact algorithm is the possibility of encountering promotion failures. These failures occur when the garbage collector is attempting to move objects from the old generation to the young generation at the same time as the program (also known as the mutator) is modifying the objects.

To make sure this doesn’t happen you would either increase the size of the old generation (or the entire heap for that matter) or allocate more background threads to the collector for him to compete with the rate of object allocation.

Another downside of thiss collector is that algorithm may use more CPU in order to provide the application with higher levels of continuous throughput. This is because the algorithm uses multiple threads to scan and collect objects, which can increase CPU usage.

In most cases, for long-running server applications that cannot tolerate application freezes,that’s usually a good trade off to make.

You have to specify this JVM argument to make CGC enable:

java -XX:+USeParNewGC -jar myapp.jar

Garbage first collector (G1) is the newest garbage collector in Java and is designed to handle large heap sizes efficiently. It divides the heap into small regions and collects garbage in those regions that have the most free space, which can help to reduce pause times.

The G1 collector then uses multiple background threads to scan through these regions, looking for objects that are no longer in use. This allows the G1 collector to target and collect garbage in the regions that have the most free space, which can help to reduce pause times and improve the overall performance of the garbage collection process.

Introduced in JDK 7 update 4 was designed to better support heaps larger than 4GB.

G1 collector is geared towards scanning those regions that contain the most garbage objects first, giving it its name (Garbage first).

You have to specify this JVM argument to make G1 enable:

java –XX:+UseG1GC -jar myapp.jar

Java 8 and the G1 Collector

Another beautiful optimization introduced in Java 8 update 20 is String Deduplication in the G1 garbage collector. This optimization helps to reduce the amount of memory used by the application by identifying and eliminating duplicate strings. When string deduplication is enabled, the garbage collector will periodically scan the heap for duplicate strings and replace them with a single shared instance. This can significantly reduce the memory footprint of the application and improve overall performance.

You can use the -XX:+UseStringDeduplicationJVM argument to try this out.

Key notes to remember:Garbage collection is the process of identifying and eliminating unused objects in Heap Memory. The garbage collector scans the heap, determines which objects are no longer needed, and reclaims the memory occupied by those objects.Garbage collection is carried out by a demon thread called Garbage Collector.GC can not be forced to happen. System.gc() can be performed but it is not guaranteed! we should never invoke that explicitly, for a number of reasons; It’s costly, It doesn’t trigger the garbage collection immediately and JVM knows better when GC needs to be called.Parallel Collector / Throughput Collector is the JVM’s default collector.ReferencesHotSpot Virtual Machine Garbage Collection Tuning GuideThe parallel collector (also referred to here as the throughput collector) is a generational collector similar to the…

docs.oracle.com

Java Garbage Collection BasicsThis OBE covers the basics of Java Virtual Machine(JVM) Garbage Collection (GC) in Java. In the first part of the OBE…

www.oracle.com

相关推荐: